<?php
/**
 * Created by PhpStorm.
 * User: George
 * Date: 2017/9/25
 * Time: 10:19
 */

namespace AdminBundle\Task;


abstract class Task
{
//    use ApiMowhereTrait;

    protected $task;
    protected $em;
    private $crypt3Des;
    private $debug;

    public function __construct($debug = false)
    {
        $this->debug = $debug;
    }

    abstract public function jsonTask();

    public function setDoctrineManager($em)
    {
        $this->em = $em;
        return $this;
    }

    public function setTask($task)
    {
        $this->task = $task;
        return $this;
    }

    protected function http($url, $postFields = array(), $method = 'get', $headers = array(), $timeout = 5000)
    {
        try {
            list($headers, $body) = $this->http_request_html($url, $postFields = $postFields, $method, $headers, $timeout);
        } catch (\Exception $e) {
            return "";
        }
        return $body;
    }

    protected function crypt3Des()
    {
        if ($this->crypt3Des) {
            return $this->crypt3Des;
        }
        $this->crypt3Des = new Crypt3Des();
        return $this->crypt3Des;
    }

    /**
     * 任务返回的数据格式
     * @param $content
     * @return mixed
     */
    protected function httpJson($url, $postFields = array(), $method = 'get', $headers = array(), $timeout = 10000)
    {
        if (empty($url)) {
            return json_encode($postFields);
        }
        if (!empty($postFields)) {
            $params['data'] = $this->crypt3Des()->encrypt(json_encode($postFields));
        } else
            $params = $postFields;
        if ($this->debug) {
            dump($url);
        }
        $content = $this->http($url, $params, $method, $headers, $timeout);

        if (empty($content)) return null;

        $decryptCotent = $this->crypt3Des()->decrypt($content);
        if ($this->debug) {
            dump($decryptCotent);
        }
        
        return json_decode($decryptCotent, true);
    }

    /**
     * http请求
     * @param $url
     * @param array $postFields
     * @param string $method
     * @param array $headers
     * @param int $timeout
     * @return array
     * @throws RuntimeException
     * @throws \Exception
     */
    private function http_request_html($url, $postFields = array(), $method = 'get', $headers = array(), $timeout = 5000)
    {
        $http_user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0';

        if (false === $curl = curl_init()) {
            throw new \RuntimeException('Unable to create a cURL handle.');
        }

        if (isset($headers['user_agent'])) {
            $http_user_agent = $headers['user_agent'];
        }

        curl_setopt($curl, CURLOPT_USERAGENT, $http_user_agent);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        curl_setopt($curl, CURLOPT_URL, $url);
//        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json'));
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        if ($post_method = !empty($postFields)) {
            curl_setopt($curl, CURLOPT_POST, $post_method);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
        }
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_MAXREDIRS, 3);

        $response = curl_exec($curl);

        if (false === $response) {
            $error = curl_error($curl);
            curl_close($curl);

            throw new \RuntimeException(sprintf('An error occurred: %s.', $error));
        }

        $headersSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $headers = substr($response, 0, $headersSize);
        $body = substr($response, $headersSize);

        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);

        if (400 == $statusCode) {
            $data = json_decode($body, true);
            $error = $data['error'];

//            throw new RuntimeException($error);
            throw new \Exception($error);
        }

        if (200 != $statusCode) {
//            throw new RuntimeException(sprintf('The web service failed for an unknown reason (HTTP %s).', $statusCode));
            throw new \Exception(sprintf('The web service failed for an unknown reason (HTTP %s).', $statusCode));
        }

        return array($headers, $body);
    }

}